//
//  ProfileHomeViewModel.swift
//  App_Profile
//
//  Created by 蒋晨成 on 2022/1/17.
//

import Adaptor
import Base
import Center
import Foundation
import RxCocoa
import RxSwift
import UICore
import UIKit

class ProfileHomeViewModel: ViewModel {
    var disposeBag: DisposeBag

    private let avatar = BehaviorRelay<String>(value: UserCenter.userInfo?.avatar ?? "")
    private let name = BehaviorRelay<String>(value: UserCenter.userInfo?.username ?? ProfileModular.localizedString(key: "Profile.Home.Info.Username.Placeholder"))
    private let signature = BehaviorRelay<String>(value: UserCenter.userInfo?.signature ?? ProfileModular.localizedString(key: "Profile.Home.Info.Signature.Placeholder"))
    private let refresh = PublishSubject<Bool>()

    init(disposeBag: DisposeBag) {
        self.disposeBag = disposeBag
        super.init()
        UserCenter.appendProfileChangeHandler(handler: self)
        resetData()
    }

    deinit {
        UserCenter.removeProfileChangeHandler(handler: self)
    }
}

extension ProfileHomeViewModel {
    func resetData() {
        name.accept(UserCenter.userInfo?.username ?? ProfileModular.localizedString(key: "Profile.Home.Info.Username.Placeholder"))
        signature.accept(UserCenter.userInfo?.signature ?? ProfileModular.localizedString(key: "Profile.Home.Info.Signature.Placeholder"))
        avatar.accept(UserCenter.userInfo?.avatar ?? "")
        refresh.onNext(false)
    }
}

extension ProfileHomeViewModel: UserCenterProfileChangeProtocol {
    func userProfileDidChange() {
        resetData()
    }
}

extension ProfileHomeViewModel {
    struct Input {
        let refreshData: Observable<Void>
    }

    struct Output {
        let avatar: Observable<String>
        let name: Observable<String>
        let signature: Observable<String>
        let refresh: Observable<Bool>
    }

    func transform(input: Input) -> Output {
        bindRefreshData(input.refreshData)

        return Output(
            avatar: avatar.asObservable(),
            name: name.asObservable(),
            signature: signature.asObservable(),
            refresh: refresh.asObserver()
        )
    }
}

private extension ProfileHomeViewModel {
    func bindRefreshData(_ refreshData: Observable<Void>) {
        refreshData.asObservable()
            .flatMapLatest { [weak self] () -> Observable<Void> in
                guard let self = self else { return Observable.just(()) }
                guard UserCenter.isLogin else { return Observable.just(()) }
                return self.loadMy()
            }
            .subscribe(onNext: { [weak self] _ in
                self?.resetData()
            })
            .disposed(by: disposeBag)
    }

    func loadMy() -> Observable<Void> {
        Observable<Void>.create { observer in
            UserCenter.getMyProfile { result in
                switch result {
                case .failure(let error):
                    observer.onError(error)
                case .success:
                    observer.onNext(())
                    observer.onCompleted()
                }
            }
            return Disposables.create()
        }
    }
}
